package com.css.zfzx.sjcj.modules.imageupload.service.Impl;

import com.css.zfzx.sjcj.modules.imageupload.service.ImageUploadService;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import org.springframework.web.multipart.MultipartFile;
import sun.misc.BASE64Decoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;

@Service
@PropertySource(value = "classpath:platform-config.yml")
public class ImageUploadServiceImpl implements ImageUploadService {
    @Value("${image.localDir}")
    private String localDir;
    @Value("${image.urlPre}")
    private String urlPre;

    @Override
    public String uploadPic(MultipartFile uploadFile) throws IOException {

        // 1.判断是否为图片 abc.jpg
        String fileName = uploadFile.getOriginalFilename();
        // 使用正则表达式进行判断
        if (!fileName.matches("^.*(jpg|png|gif)$")) { // . 代表任意的字符 * 代表有任意多个 的
            // 表示不是图片
            int i = 0;
            i++;
            String imageMessage = "第" + i + "张不是图片";
            return "不是图片";
        }
        try {
            /**
             * ImageIO是javax下面的一个工具类
             */
            // 2.判断是否为恶意程序 uploadFile.getInputStream() 文件流
            BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
            // 3.获取图片宽度和高度 (图片宽高为 0 ,则图片是假的图片)
            int height = bufferedImage.getHeight();
            int width = bufferedImage.getWidth();
            if (height == 0 || width == 0) {// 假图片
                int i = 0;
                i++;
                String imageMessage = "第" + i + "张假图片";
                return "假图片";
            }
            // 4.准备文件存储的路径()
            //String localDir = "D:/IdeaProjects/fwsjcj/src/main/webapp/static/image"; // 本地文件夹
            // 5.实现分文件存储 yyyy/MM/dd 以 天 为单位 分文件
            String dateDir = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
            // 6.形成保存图片的文件夹 d:/file/yyyy/MM/dd (文件存储的根目录)
            //String picDir = localDir + dateDir;
            // 7.生成文件夹
            File picFile = new File(localDir); // 文件夹的文件执行
            if (!picFile.exists()) { // 文件夹不存在 就创建文件夹
                picFile.mkdirs();
            }
            // 8.重命名上传的文件名字 (避免重名)
            String uuid = UUID.randomUUID().toString().replace("-", ""); // asa22exac-adsfafadsf-3fddsfds
            // 生成随机数
            int randomNum = new Random().nextInt(999); // 生成随机数 (0-999)
            // 获取文件的后缀名
            String fileType = fileName.substring(fileName.lastIndexOf(".")); // .jpg
            // 拼文件名
            String realFileName = uuid + randomNum + fileType; // 真实的文件名称
            // 9生成文件的本地磁盘的路径 d:/file/yyyy/MM/dd/wqrwadasfiuoew800.jpg
            String localPath = localDir + "/" + realFileName;
            localPath = localPath.replace("/", "\\");
            // 10实现文件的上传
            uploadFile.transferTo(new File(localPath));

            // 11添加文件的宽度,高度 需要返回
            //result.setHeight(height + "");
            //result.setWidth(width + "");

            // 12准备文件的虚拟路径
            // http://image.jt.com/file/2018/05/07/radweedwsaf210.jpg
            //String urlPre = "http://10.33.0.164:8081/static/image";

            String urlPath = urlPre + "/" + realFileName;
            return urlPath;
        } catch (IOException e) { // 不是图片会抛异常
            e.printStackTrace();
            //result.setError(1); // 表示为恶意程序
            int i = 0;
            i++;
            String imageMessage = "第" + i + "张恶意程序";
            return "恶意程序";
        }


    }

    @Override
    public List<String> uploadPics(MultipartFile[] multipartFiles, String buildingCode) throws IOException {
        List<String> stringList = new ArrayList<>();
        if (multipartFiles != null && multipartFiles.length > 0) {
            for (int i = 0; i < multipartFiles.length; i++) {
                MultipartFile file = multipartFiles[i];
                String fileName = file.getOriginalFilename();
                if (!fileName.matches("^.*(jpg|png|gif)$")) {
                    List<String> msgList = new ArrayList<>();
                    msgList.add("第" + (i + 1) + "张不是图片");
                    return msgList;
                }
                try {
                    BufferedImage bufferedImage = ImageIO.read(file.getInputStream());
                    int height = bufferedImage.getHeight();
                    int width = bufferedImage.getWidth();
                    if (height == 0 || width == 0) {
                        List<String> msgList = new ArrayList<>();
                        msgList.add("第" + (i + 1) + "张是假图片");
                        return msgList;
                    }
                    String dateDir = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
                    String savePath = localDir + File.separator + dateDir;
                    // 不存在就创建文件夹
                    File imgFile = new File(savePath);
                    if (!imgFile.exists()) {
                        imgFile.mkdirs();
                    }
                    String fileType = fileName.substring(fileName.lastIndexOf("."));//获取后缀名
                    //获取的时分秒毫秒
                    String hHmmssSSS = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HHmmssSSS"));

                    String realFileName = buildingCode +"_"+hHmmssSSS+"_000"+ (i+1) + fileType;
                    //输出文件
                    String outFile= savePath+File.separator+realFileName;
                    byte[] file2byte = File2byte(file.getInputStream());
                    OutputStream os = new FileOutputStream(outFile);
                    os.write(file2byte);
                    os.close();
                    //FileOutputStream fos=new FileOutputStream(outFile);
                    //创建一个指向 fos的JPEGImageEncoder对象
                    //JPEGImageEncoder je= JPEGCodec.createJPEGEncoder(fos);
                    //je.encode(bufferedImage);
                    //fos.close();
                    /*file.transferTo(new File(outFile));*/
                    String imagePath = urlPre + "/" + dateDir + "/" + realFileName;
                    //String urlPath = urlPre + "/" + realFileName;
                    stringList.add(imagePath);
                } catch (Exception e) {
                    e.printStackTrace();
                    stringList.add("第" + (i + 1) + "张是恶意程序");
                    return stringList;
                }
            }
        }
        return stringList;
    }

    public static byte[] File2byte(InputStream fis){
        byte[] buffer = null;
        try
        {
            ByteArrayOutputStream bos = new ByteArrayOutputStream();
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1)
            {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        }catch (FileNotFoundException e){
            e.printStackTrace();
        }catch (IOException e){
            e.printStackTrace();
        }
        return buffer;
    }


    @Override
    public String uploadPicList(MultipartFile uploadFile, String buildingCode) {
        // 1.判断是否为图片 abc.jpg
        String fileName = uploadFile.getOriginalFilename();
        // 使用正则表达式进行判断
        if (!fileName.matches("^.*(jpg|png|gif|jpeg)$")) { // . 代表任意的字符 * 代表有任意多个 的
            // 表示不是图片
            return "不是图片";
        }
        try {
            /**
             * ImageIO是javax下面的一个工具类
             */
            // 2.判断是否为恶意程序 uploadFile.getInputStream() 文件流
            BufferedImage bufferedImage = ImageIO.read(uploadFile.getInputStream());
            // 3.获取图片宽度和高度 (图片宽高为 0 ,则图片是假的图片)
            int height = bufferedImage.getHeight();
            int width = bufferedImage.getWidth();
            if (height == 0 || width == 0) {// 假图片
                int i = 0;
                i++;
                String imageMessage = "第" + i + "张假图片";
                return "假图片";
            }
            // 4.准备文件存储的路径()
            //String localDir = "D:/IdeaProjects/fwsjcj/src/main/webapp/static/image"; // 本地文件夹
            // 5.实现分文件存储 yyyy/MM/dd 以 天 为单位 分文件
            String dateDir = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
            // 6.形成保存图片的文件夹 d:/file/yyyy/MM/dd (文件存储的根目录)
            //String picDir = localDir + dateDir;
            // 7.生成文件夹
            File picFile = new File(localDir); // 文件夹的文件执行
            if (!picFile.exists()) { // 文件夹不存在 就创建文件夹
                picFile.mkdirs();
            }
            // 8.重命名上传的文件名字 (避免重名)
            String uuid = UUID.randomUUID().toString().replace("-", ""); // asa22exac-adsfafadsf-3fddsfds
            // 生成随机数
            int randomNum = new Random().nextInt(999); // 生成随机数 (0-999)
            // 获取文件的后缀名
            String fileType = fileName.substring(fileName.lastIndexOf(".")); // .jpg

            // 9生成文件的本地磁盘的路径 d:/file/yyyy/MM/dd/wqrwadasfiuoew800.jpg
            //获取的时分秒毫秒
            String hHmmssSSS = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HHmmssSSS"));
            // 拼文件名// 真实的文件名称
            int i=0;
            String realFileName = buildingCode +"_"+hHmmssSSS+"_000"+ (i+1) + fileType;
            String localPath = localDir + "/" + realFileName;
            localPath = localPath.replace("/", "\\");
            // 10实现文件的上传
            uploadFile.transferTo(new File(localPath));

            // 11添加文件的宽度,高度 需要返回
            //result.setHeight(height + "");
            //result.setWidth(width + "");

            // 12准备文件的虚拟路径
            // http://image.jt.com/file/2018/05/07/radweedwsaf210.jpg
            //String urlPre = "http://10.33.0.164:8081/static/image";

            String urlPath = urlPre + "/" + realFileName;
            return urlPath;
        } catch (IOException e) { // 不是图片会抛异常
            e.printStackTrace();
            //result.setError(1); // 表示为恶意程序
            int i = 0;
            i++;
            String imageMessage = "第" + i + "张恶意程序";
            return "恶意程序";
        }
    }

    @Override
    public  List<String> uploadBase64(String[] base64Info, String buildingCode) {

        if(base64Info.length<=0){
            return null;
        }else {
            List<String> listPre = new ArrayList<>();
            for (int i=0;i<base64Info.length;i++) {
                if(!StringUtils.isEmpty(base64Info[i])){
                    if(!String.valueOf(base64Info[i]).contains("data:image")){
                        listPre.add(String.valueOf(base64Info[i]));
                    }else {
                        //图片名称
                        String hHmmssSSS = LocalDateTime.now().format(DateTimeFormatter.ofPattern("HHmmssSSS"));
                        String realFileName = buildingCode + "_" + hHmmssSSS + "_000" + (i + 1) + ".jpeg";
                        //确保图片名称的唯一性
                        //本地存储路径
                        String dateDir = new SimpleDateFormat("yyyy/MM/dd").format(new Date());
                        String savePath = localDir + File.separator + dateDir;
                        //输出文件
                        String outFile= savePath+File.separator+realFileName;
                        //虚拟路径
                        String imagePath = urlPre + File.separator + dateDir + File.separator + realFileName;
                        try {
                            BASE64Decoder decoder = new BASE64Decoder();
                            byte[] data = decoder.decodeBuffer(String.valueOf(base64Info[i]).split(",")[1]);
                            // 调整异常数据
                            for (int j = 0; j < data.length; ++j) {
                                if (data[j] < 0) {
                                    data[j] += 256;
                                }
                            }
                            File file = new File(savePath);
                            if (!file.exists()) {
                                file.mkdirs();
                            }
                            OutputStream os = new FileOutputStream(outFile);
                            os.write(data);
                            os.close();
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                        listPre.add(imagePath);
                      }
                }
            }
         return listPre;
        }
    }
}
